<template>
  <div class="w-input" :class="{validate: validate, error: hasError}">
    <span class="error-tip" v-show="hasError" v-text="errorText"></span>
    <span class="rule-tip" v-show="!hasError" v-text="tip"></span>
    <textarea v-if="type==='textarea'" class="form-control" ref="input"
      :value="value"
      :name="name"
      :maxlength="maxlength"
      :disabled="disabled"
      :placeholder="holder"
      @input="onUpdateValue($event.target.value)"
      @blur="onValidate"
      @focus="hasError = false">
    </textarea>
    <input v-if="type==='password'" class="form-control" ref="input"
      type="password"
      :value="value"
      :name="name"
      :maxlength="maxlength"
      :disabled="disabled"
      :placeholder="holder"
      @input="onUpdateValue($event.target.value)"
      @blur="onValidate"
      @focus="hasError = false"
      autocomplete="new-password" >
    <input v-if="type==='text'" class="form-control" ref="input"
      type="text"
      :value="value"
      :name="name"
      :maxlength="maxlength"
      :disabled="disabled"
      :placeholder="holder"
      @input="onUpdateValue($event.target.value)"
      @blur="onValidate"
      @change="onChange"
      @focus="hasError = false">
  </div>
</template>

<script>
import Rule from './rule'
export default {
  props: {
    value: [String, Number],
    type: {
      type: String,
      default: 'text'
    },
    name: {
      type: String,
      default: null
    },
    maxlength: {
      type: Number,
      default: null
    },
    validate: {
      type: Boolean,
      default: true
    },
    rule: {
      type: String,
      default: 'isEmpty'
    },
    error: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    tip: {
      type: String,
      default: ''
    },
    holder: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      inputVal: '',
      validateArr: [],
      hasError: false,
      errorText: ''
    }
  },
  created() {
    this._mergeValidateArr()
  },
  methods: {
    onUpdateValue(val) { // 每次输入更新value，并过滤前后空格
      let trimVal = val.trim()
      if (trimVal != val) {
        this.$refs.input.value = trimVal
      }
      this.$emit('input', trimVal)
    },
    onValidate() { // 鼠标失去焦点进行验证
      if (this.validate) {
        this._validateInput()
      }
      this.$emit('on-blur')
    },
    onChange() { // 更改input框的值时进行验证
      if (this.validate) {
        this._validateInput()
      }
      this.$emit('on-change')
    },
    _validateInput() { // 进行验证
      const aValidate = this.validateArr
      let errMsg = ''
      for (let i = 0; i < aValidate.length; i++) {
        const pattern = aValidate[i].pattern
        const aPattern = pattern.split('|')
        if (aPattern.length === 1) {
          errMsg = Rule[pattern](this.value, aValidate[i].errorText)
        } else {
          errMsg = Rule[aPattern[0].toString()](this.value, aPattern[1].toString(), aValidate[i].errorText)
        }
        if (errMsg) {
          this.hasError = true
          this.errorText = errMsg
          return true
        } else {
          this.hasError = false
          errMsg = null
        }
      }
    },
    /**
     * 合并校验规则，错误提示，以'|'为标志
     */
    _mergeValidateArr() {
      const aRule = this.rule.split('|')
      const aValid = this.error.split('|')
      aRule.forEach((item, index) => {
        this.validateArr.push({
          pattern: item,
          errorText: aValid[index]
        })
      })
    }
  }
}
</script>

<style lang="scss">
  @import '../../scss/_var.scss';
  .w-input {
    position: relative;
    &.error {
      .form-control {
        transition: all .1s;
        border-color: $color-error;
      }
    }
    .error-tip {
      position: absolute;
      margin-top: 32px;
      color: $color-error;
    }
    .rule-tip {
      position: absolute;
      margin-top: 32px;
      color: $color-gray;
    }
    input {
      width: 100%;
      height: auto;
    }
  }
</style>